var Promise=require('tf-utils/class/Promise').default;
var objectAssign=require('tf-utils/lib/objectAssign').default;
const DB_NAME='any-study';
const DB_VERSION=4;

const OS_STUDY='study';
const READ_WRITE='readwrite';
const READ_ONLY='readonly';

/**
 * （元操作）打开数据库
 */
function open(){
    return new Promise(resolve => {
        const request = window.indexedDB.open(DB_NAME, DB_VERSION);
        request.onerror = function (e) {
            console.log(e.currentTarget.error.message);
        };
        request.onsuccess = function (e) {
            resolve(e.target.result);
        };
        request.onupgradeneeded = function (e) {
            var db = e.target.result;
            var store;
            //创建表
            //记录表
            if (!db.objectStoreNames.contains(OS_STUDY)) {
                store = db.createObjectStore(OS_STUDY, {autoIncrement: true});
            }else{
                var transaction=e.target.transaction;
                store=transaction.objectStore(OS_STUDY);
                //删除所有索引
                var names=store.indexNames;
                for(var i=0;i<names.length;i++){
                    store.deleteIndex(names[i]);
                }
            }
            store.createIndex('type', 'type', {unique: false});
            store.createIndex('name', 'name', {unique: true});

            console.log('DB version changed to ' + DB_VERSION);
        };
    })
}

/**
 * （元操作）指定对象存储空间
 * @param db
 * @param storeName
 * @param mode
 * @returns {*}
 */
function getObjectStore(db, mode, storeName){
    if(!storeName){
        storeName=OS_STUDY;
    }
    return db.transaction(storeName, mode||READ_ONLY).objectStore(storeName);
}

/**
 * （元操作）获取一条数据
 * @param store
 * @param id 主键字段
 */
function getObj(store, id){
    return new Promise(resolve => {
        const request=store.get(+id);
        request.onsuccess=function(e){
            resolve(e.target.result);
        };
    })
}

/**
 * （元操作）根据索引一条数据
 * @param index
 * @param value
 * @returns {*|Promise}
 */
function getIndex(index, value){
    return new Promise(resolve => {
        const request=index.get(value);
        request.onsuccess=function(e){
            resolve(e.target.result);
        };
    })
}

/**
 * （元操作）获取游标
 * @param storeOrIndex
 * @param idbKeyRange
 * @param idbCursor
 */
function getCursor(storeOrIndex, idbKeyRange, idbCursor){
    return new Promise(resolve => {
        const request=storeOrIndex.openCursor(idbKeyRange, idbCursor);
        var list=[];
        request.onsuccess=function(e){
            var cursor=e.target.result;
            if(cursor){
                var data=cursor.value;
                data.id=cursor.primaryKey;
                list.push(cursor.value);
                cursor.continue();
            }else {
                resolve(list);
            }
        };
    })
}

/**
 * 获取一条数据
 * @param id
 * @returns {Promise|Promise.<T>}
 */
function get(id){
    var _db;
    return open()
        .then(db => {
            _db=db;
            return getObjectStore(db);
        })
        .then(store => getObj(store, id))
        .then(obj => {
            _db.close();

            return obj;
        })
    ;
}

/**
 * 根据获取一条数据
 * @param name
 * @returns {Promise|Promise.<T>}
 */
function getByName(name){
    var _db;
    return open()
        .then(db => {
            _db=db;
            return getObjectStore(db);
        })
        .then(store => getIndex(store.index('name'), name))
        .then(obj => {
            _db.close();

            return obj;
        })
        ;
}

/**
 * 获取指定条件的数据列表
 * @param indexName
 * @returns {Promise|Promise.<T>}
 */
function getList(indexName){
    var _db;
    return open()
        .then(db => {
            _db=db;
            return getObjectStore(db);
        })
        .then(store => indexName?getCursor(store.index('type'), IDBKeyRange.only(indexName)):getCursor(store))
        .then(list => {
            _db.close();

            return list;
        })
        ;
}

/**
 * 插入一条数据
 * @param data
 */
function add(data){
    var _db;
    open()
        .then(db => {
            _db=db;
            return getObjectStore(db, READ_WRITE);
        })
        .then(store => {
            store.add(data);

            _db.close();
        })
    ;
}

/**
 * 更新
 * @param id 主键字段
 * @param data 保存的对象
 */
function save(id, data){
    var _db;
    var _store;
    open()
        .then(db => {
            _db=db;
            return getObjectStore(db, READ_WRITE);
        })
        .then(store => {
            _store=store;
            return getObj(store, id);
        })
        .then(obj => {
            objectAssign(obj, data);
            _store.put(obj, +id);

            _db.close();
        })
    ;
}

/**
 * 删除
 * @param id 主键字段,不传则为删除全部
 */
function del(id){
    var _db;
    open()
        .then(db => {
            _db=db;
            return getObjectStore(db, READ_WRITE);
        })
        .then(store => {
            if(id) {
                store.delete(+id);
            }else{
                store.clear();
            }

            _db.close();
        })
    ;
}

/**
 * 批量添加
 * @param dataList
 */
function addList(dataList){
    var _db;
    open()
        .then(db => {
            _db=db;
            return getObjectStore(db, READ_WRITE);
        })
        .then(store => {
            dataList.forEach(data => {
                store.add(data);
            });

            _db.close();
        })
    ;
}

module.exports={
    get:get,
    getByName:getByName,
    getList:getList,
    add:add,
    addList:addList,
    save:save,
    del:del
};